package love.contact.data;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import love.contact.R;
import love.contact.engine.ContactIconOperateDelegate;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import wwk.common.util.FileUtil;
import android.content.ContentProviderOperation;
import android.content.ContentProviderOperation.Builder;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.RawContacts;

public class Contact {

	private int id;
	private String displayName;
	private String familyName;
	private String givenName;
	private String middleName;
	private String prefix;
	private String suffix;
	private String phoneticFamilyName;
	private String phoneticGivenName;
	private String phoneticMiddleName;
	private List<PhoneStruct> phoneStructArray;
	private List<AttributeValueStruct> emailStructArray;
	public int iconStart;
	public int iconLength;
	private String ringTone;
	private List<AttributeValueStruct> addressStructArray;
	private List<AttributeValueStruct> organizationStructArray;
	
	public Contact()
	{
		phoneStructArray=new ArrayList<PhoneStruct>();
		emailStructArray=new ArrayList<AttributeValueStruct>();
		addressStructArray=new ArrayList<AttributeValueStruct>();
		organizationStructArray=new ArrayList<AttributeValueStruct>();
	}
	
	public Contact(int id)
	{
		this.id=id;
		phoneStructArray=new ArrayList<PhoneStruct>();
		emailStructArray=new ArrayList<AttributeValueStruct>();
		addressStructArray=new ArrayList<AttributeValueStruct>();
		organizationStructArray=new ArrayList<AttributeValueStruct>();
	}

	static public int getContactId(Cursor cursor)
	{
		int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
		return id;
	}
	
	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	static public Object[] getContactNameAndIcon(Context context,int contactId)
	{
		Object[] objs=null;
		
		String name=null;
		String photoId=null;
		
		String selection="("+contactId+")";
		Cursor cursor=Contact.openContactCursor(context, selection,true);
		if(cursor.moveToFirst())
		{
			objs=new Object[2];
			
			name = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
			objs[0]=name;
			
			photoId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
			if(photoId!=null)
			{
				String selection1 = ContactsContract.Data._ID + " = " + photoId;
				String[] projection = new String[] { ContactsContract.Data.DATA15 };
	            Cursor cur = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection1, null, null);
	            if(cur.moveToFirst())
	            {
	            	byte[] iconBytes = cur.getBlob(0);
	            	Bitmap map = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
	            	objs[1]=map;
	            }
	            cur.close();
			}
		}
		cursor.close();
			
		return objs;
	}

	static public boolean isContactExists(Context context,int contactId)
	{
		boolean exists=false;
		
		String selection="("+contactId+")";
		Cursor cursor=Contact.openContactCursor(context, selection,true);
		if(cursor.moveToFirst())
		{
			exists=true;
		}
		cursor.close();
			
		return exists;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	public List<PhoneStruct> getPhoneStructArray() {
		return phoneStructArray;
	}
	
	public String toString()
	{
		return displayName;
	}
	
	//insert to sqlite db
	public boolean insert(Context context,InputStream iconFileInputStream)
	{
		boolean ret=false;
		
		//ContentResolver
		ContentResolver resolver = context.getContentResolver();
		
		//transaction
		ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();  
		
		Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);//RawContacts
		ContentProviderOperation operation=builder.withValue(ContactsContract.Contacts._ID, null)
													.build();
		operations.add(operation);
		
		//name
		builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
		operation=builder.withValueBackReference(Data.RAW_CONTACT_ID, 0)
						.withValue(Data.MIMETYPE,StructuredName.CONTENT_ITEM_TYPE)
						.withValue(StructuredName.DISPLAY_NAME,displayName)
						.withValue(StructuredName.FAMILY_NAME,familyName)
						.withValue(StructuredName.GIVEN_NAME,givenName)
						.withValue(StructuredName.MIDDLE_NAME,middleName)
						.withValue(StructuredName.PREFIX,prefix)
						.withValue(StructuredName.SUFFIX,suffix)
						.withValue(StructuredName.PHONETIC_FAMILY_NAME,phoneticFamilyName)
						.withValue(StructuredName.PHONETIC_GIVEN_NAME,phoneticGivenName)
						.withValue(StructuredName.PHONETIC_MIDDLE_NAME,phoneticMiddleName)
						.build();
		operations.add(operation);

		//phone
		if(phoneStructArray!=null)
		{
			for(PhoneStruct phone : phoneStructArray)
			{
				builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
				operation=builder.withValueBackReference(Data.RAW_CONTACT_ID, 0)
								.withValue(Data.MIMETYPE,Phone.CONTENT_ITEM_TYPE)
								.withValue(StructuredName.DATA1,phone.getNumber())
								.withValue(StructuredName.DATA2,phone.getType())
								.withValue(Phone.LABEL,phone.getLabel())
								.build();
				operations.add(operation);
			}
		}
		
		//mail
		if(emailStructArray!=null)
		{
			for(AttributeValueStruct emailStruct : emailStructArray)
			{
				builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
				operation=builder.withValueBackReference(Data.RAW_CONTACT_ID, 0)
								.withValue(Data.MIMETYPE,Email.CONTENT_ITEM_TYPE)
								.withValue(StructuredName.DATA1,emailStruct.getValue(0))
								.withValue(StructuredName.DATA2,emailStruct.getType())
								.withValue(Email.LABEL,emailStruct.getLabel())
								.build();
				operations.add(operation);
			}
		}
		
		//address
		if(addressStructArray!=null)
		{
			for(AttributeValueStruct struct : addressStructArray)
			{
				builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
				operation=builder.withValueBackReference(Data.RAW_CONTACT_ID, 0)
								.withValue(Data.MIMETYPE,StructuredPostal.CONTENT_ITEM_TYPE)
								.withValue(StructuredPostal.CITY,struct.getValue(0))
								.withValue(StructuredPostal.STREET,struct.getValue(1))
								.withValue(StructuredPostal.POSTCODE,struct.getValue(2))
								.withValue(StructuredPostal.REGION,struct.getValue(3))
								.withValue(StructuredPostal.COUNTRY,struct.getValue(4))
								.withValue(StructuredPostal.POBOX,struct.getValue(5))
								.withValue(StructuredPostal.NEIGHBORHOOD,struct.getValue(6))
								.withValue(StructuredPostal.TYPE,struct.getType())
								.withValue(StructuredPostal.LABEL,struct.getLabel())
								.build();
				operations.add(operation);
			}
		}
				
		//orgnization
		if(organizationStructArray!=null)
		{
			for(AttributeValueStruct struct : organizationStructArray)
			{
				builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
				operation=builder.withValueBackReference(Data.RAW_CONTACT_ID, 0)
								.withValue(Data.MIMETYPE,Organization.CONTENT_ITEM_TYPE)
								.withValue(Organization.COMPANY,struct.getValue(0))
								.withValue(Organization.TITLE,struct.getValue(1))
								.withValue(Organization.TYPE,struct.getType())
								.withValue(Organization.LABEL,struct.getLabel())
								.build();
				operations.add(operation);
			}
		}
		
		//head
		boolean addIconRet=false;
		if(iconLength>0 && iconFileInputStream!=null)
		{
			byte[] iconBytes=FileUtil.read(iconFileInputStream,iconLength);
			builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
			operation=builder.withValueBackReference(Data.RAW_CONTACT_ID, 0)
							.withValue(Data.MIMETYPE,Photo.CONTENT_ITEM_TYPE)
							.withValue(StructuredName.DATA15,iconBytes)
							.build();
			addIconRet=operations.add(operation);
		}
	
		try 
		{
			/*
			 * /raw_contacts/578
			 * /data/12341
			 * /data/12342
			 * /data/12343
			 * */
			int rawContactId=0;
			ContentProviderResult[] resultArray=resolver.applyBatch(ContactsContract.AUTHORITY, operations);
			if(resultArray!=null && resultArray.length>0)
			{
				for(ContentProviderResult result : resultArray)
				{
					if( result.uri.getPath().indexOf(RawContacts.CONTENT_URI.getLastPathSegment())>0)
					{
						rawContactId=Integer.valueOf(result.uri.getLastPathSegment());
						break;
					}
				}
				
				ret=true;
			}
			
			if(ringTone!=null)
			{
				ContentValues values = new ContentValues();  
				values.put(Contacts.CUSTOM_RINGTONE, ringTone);  
				resolver.update(RawContacts.CONTENT_URI, values, RawContacts._ID + " = " + rawContactId, null) ; 
			}
			
			if(rawContactId>0)
			{
				Cursor cursor = context.getContentResolver().query(RawContacts.CONTENT_URI, new String[]{RawContacts.CONTACT_ID}, RawContacts._ID+"="+rawContactId, null, null);
				if(cursor.moveToFirst())
				{
					id=cursor.getInt(0);
				}
				cursor.close();
			}
		} 
		catch (RemoteException e) 
		{
			e.printStackTrace();
		} 
		catch (OperationApplicationException e) 
		{
			e.printStackTrace();
		}  
		
		return ret;
	}

	//Returns: The number of rows deleted.
	static public int deleteAll(Context context) 
	{
		//delete operations effect immediately, ContactsContract.CALLER_IS_SYNCADAPTER=true.
		//index begin from 1,delete all raw contact where id>0
		Uri uri=Uri.parse(ContactsContract.RawContacts.CONTENT_URI.toString() +"?" +ContactsContract.RawContacts._ID + ">0");
		
		//appendQueryParameter
		Uri.Builder b = uri.buildUpon();
		b.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER,"true");
		uri = b.build();
		
		return context.getContentResolver().delete(uri,null,null);
	}
	
	static public String getColumnValue(Cursor cursor,String columnName)
	{
		String value=null;
		if(cursor.getColumnIndex(columnName)>=0)
		{
			value=cursor.getString(cursor.getColumnIndex(columnName));
		}
		return value;
	}
	
	static public void addTag(XmlSerializer serializer,String tag,String text)
	{
		if(text!=null && text.length()>0)
        {
			try
			{
	            serializer.startTag("", tag);
	            serializer.text(text);
	            serializer.endTag("", tag);
			}
			catch (Exception e) 
		    {
		        e.printStackTrace();
		    }
        }
	}
	
	static public void export(Context context,XmlSerializer serializer,Handler handler,ContactIconOperateDelegate delegate)
	{
		Cursor cursor=Contact.openContactCursor(context,null,false);
		while(cursor.moveToNext())
		{
			try 
		    {
				//namespace
		        serializer.startTag("", "contact");
		        
				//id
				int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
	            serializer.attribute("", "id", id+"");
	            
	            //name
	            String DISPLAY_NAME = null;
				String FAMILY_NAME = null;
				String GIVEN_NAME = null;
				String MIDDLE_NAME = null;
				String PREFIX = null;
				String SUFFIX = null;
				String PHONETIC_FAMILY_NAME = null;
				String PHONETIC_GIVEN_NAME = null;
				String PHONETIC_MIDDLE_NAME = null;
				//String name = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
				Cursor nameCursor = context.getContentResolver().query(
						ContactsContract.Data.CONTENT_URI, 
						null,
						ContactsContract.Data.CONTACT_ID + " = " + id 
						+ " and " +ContactsContract.Data.MIMETYPE +" = '"+ ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE+"'",
						null,
						null);
				if(nameCursor.moveToFirst())
				{
					DISPLAY_NAME=getColumnValue(nameCursor,StructuredName.DISPLAY_NAME);
					FAMILY_NAME=getColumnValue(nameCursor,StructuredName.FAMILY_NAME);
					GIVEN_NAME=getColumnValue(nameCursor,StructuredName.GIVEN_NAME);
					MIDDLE_NAME=getColumnValue(nameCursor,StructuredName.MIDDLE_NAME);
					PREFIX=getColumnValue(nameCursor,StructuredName.PREFIX);
					SUFFIX=getColumnValue(nameCursor,StructuredName.SUFFIX);
					PHONETIC_FAMILY_NAME=getColumnValue(nameCursor,StructuredName.PHONETIC_FAMILY_NAME);
					PHONETIC_GIVEN_NAME=getColumnValue(nameCursor,StructuredName.PHONETIC_GIVEN_NAME);
					PHONETIC_MIDDLE_NAME=getColumnValue(nameCursor,StructuredName.PHONETIC_MIDDLE_NAME);
				}
				nameCursor.close();
				serializer.startTag(null, "name");
				addTag(serializer,"display_name",DISPLAY_NAME);
				addTag(serializer,"family_name",FAMILY_NAME);
				addTag(serializer,"given_name",GIVEN_NAME);
				addTag(serializer,"middle_name",MIDDLE_NAME);
				addTag(serializer,"prefix",PREFIX);
				addTag(serializer,"suffix",SUFFIX);
				addTag(serializer,"phonetic_family_name",PHONETIC_FAMILY_NAME);
				addTag(serializer,"phonetic_given_name",PHONETIC_GIVEN_NAME);
				addTag(serializer,"phonetic_middle_name",PHONETIC_MIDDLE_NAME);
				serializer.endTag(null, "name");
	            
				serializer.startTag(null, "phones");
				Cursor phoneCursor = context.getContentResolver().query(
						ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
						null,
						ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
						null,
						null);
		
				while (phoneCursor.moveToNext())
				{
					//number
					String number = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
					if(number!=null && number.length()>0)
					{
						//type
						int type = phoneCursor.getInt(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
						
						//label
						String label=ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), type, "").toString();
						if(type==Phone.TYPE_CUSTOM)
						{
							label=phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL));
						}

						serializer.startTag(null, "phone");
		            	if(label!=null)
		            	{
		            		serializer.attribute("", "label",label);
		            	}
		            	serializer.attribute("", "number", number);
		            	serializer.attribute("", "type", ""+type);
		            	serializer.endTag(null, "phone");
					}	
				}
				phoneCursor.close();
				serializer.endTag(null, "phones");
				
				//email
				serializer.startTag(null, "emails");
				Cursor emailCursor = context.getContentResolver().query(
						ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
						null,
						ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id,
						null,
						null);
				
				//may have more email
				while (emailCursor.moveToNext())
				{
					String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
					if(email!=null && email.length()>0)
					{
						//type
						int type = emailCursor.getInt(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
						
						//label
						String label=ContactsContract.CommonDataKinds.Email.getTypeLabel(context.getResources(), type, "").toString();
						if(type==ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM)
						{
							label=emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.LABEL));
						}

						serializer.startTag(null, "email");
		            	if(label!=null)
		            	{
		            		serializer.attribute("", "label",label);
		            	}
		            	serializer.attribute("", "value", email);
		            	serializer.attribute("", "type", ""+type);
		            	serializer.endTag(null, "email");
					}	
				}
				emailCursor.close();
				serializer.endTag(null, "emails");
				
				//address
				serializer.startTag(null, "addresses");
				Cursor addressCursor = context.getContentResolver().query(
						ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, 
						null,
						ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = " + id,
						null,
						null);
				
				//may have more address
				while (addressCursor.moveToNext())
				{
					//company
					String city = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
					String street = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
					String postcode = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
					String region = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
					String country = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
					String pobox = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));
					String neighborhood = addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD));
					
					//type
					int type = addressCursor.getInt(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE));
					
					//label
					String label=ContactsContract.CommonDataKinds.StructuredPostal.getTypeLabel(context.getResources(), type, "").toString();
					if(type==ContactsContract.CommonDataKinds.StructuredPostal.TYPE_CUSTOM)
					{
						label=addressCursor.getString(addressCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.LABEL));
					}
					
					serializer.startTag(null, "address");
					serializer.attribute("", "type", ""+type);
	            	if(label!=null)
	            	{
	            		serializer.attribute("", "label",label);
	            	}
	            	
	            	serializer.attribute("", "city", city);
	            	serializer.attribute("", "street", street);
	            	serializer.attribute("", "postcode", postcode);
	            	serializer.attribute("", "region", region);
	            	serializer.attribute("", "country", country);
	            	serializer.attribute("", "pobox", pobox);
	            	serializer.attribute("", "neighborhood", neighborhood);
	            	
	            	serializer.endTag(null, "address");
				}
				addressCursor.close();
				serializer.endTag(null, "addresses");
	
				//organization
				serializer.startTag(null, "organizations");
				String orgWhere = ContactsContract.Data.CONTACT_ID + " = ?  AND "    + ContactsContract.Data.MIMETYPE + " = ?";  
				String[] orgWhereParams = new String[]{ ""+id,ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE };  
				Cursor organizationCursor = context.getContentResolver().query(
						ContactsContract.Data.CONTENT_URI, 
						null,
						orgWhere,
						orgWhereParams,
						null);
				
				//may have more organization
				while (organizationCursor.moveToNext())
				{
					//company
					String company = organizationCursor.getString(organizationCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY));
					String position = organizationCursor.getString(organizationCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE));

					//type
					int type = organizationCursor.getInt(organizationCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE));
					
					//label
					String label=ContactsContract.CommonDataKinds.Organization.getTypeLabel(context.getResources(), type, "").toString();
					if(type==ContactsContract.CommonDataKinds.Organization.TYPE_CUSTOM)
					{
						label=organizationCursor.getString(organizationCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.LABEL));
					}
					
					serializer.startTag(null, "organization");
					serializer.attribute("", "type", ""+type);
	            	if(label!=null)
	            	{
	            		serializer.attribute("", "label",label);
	            	}
	            	
	            	serializer.attribute("", "company", company);
	            	serializer.attribute("", "position", position);

	            	serializer.endTag(null, "organization");
						
				}
				organizationCursor.close();
				serializer.endTag(null, "organizations");
				
				//save photo
				String photoId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
				if(photoId!=null)
				{
					String selection1 = ContactsContract.Data._ID + " = " + photoId;
					String[] projection = new String[] { ContactsContract.Data.DATA15 };
		            Cursor cur = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection1, null, null);
		            if(cur.moveToFirst())
		            {
		            	byte[] iconBytes = cur.getBlob(0);
		            	long fileSize=delegate.appendIconBytes(iconBytes);
		            	if(fileSize>0)
		            	{
			            	serializer.startTag("", "icon");
			            	serializer.attribute("", "start", ""+(fileSize-iconBytes.length));
			            	serializer.attribute("", "length", ""+iconBytes.length);
				            serializer.endTag("", "icon");
		            	}
		            }
		            cur.close();
				}
				
				//RingTone
				String customRingTone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.CUSTOM_RINGTONE));
				if(customRingTone!=null)
				{
	            	serializer.startTag("", "ringTone");
	            	serializer.text(customRingTone);
		            serializer.endTag("", "ringTone");
				}
				
		        serializer.endTag("", "contact");
		        
		        handler.sendEmptyMessage(ContactConst.MSG_IMPORT_INCREASE);
		    } 
		    catch (Exception e) 
		    {
		        e.printStackTrace();
		    }
		}
		cursor.close();
	}

	public void parse(Context context,XmlPullParser parser)
	{
		id=0;
		displayName=null;
		familyName=null;
		givenName=null;
		middleName=null;
		prefix=null;
		suffix=null;
		phoneticFamilyName=null;
		phoneticGivenName=null;
		phoneticMiddleName=null;
		phoneStructArray.clear();
		emailStructArray.clear();
		addressStructArray.clear();
		organizationStructArray.clear();
		
		ringTone=null;
		
		int attributeCount=parser.getAttributeCount();
		for(int i= 0; i < attributeCount;i++)
		{
			String attributeName=parser.getAttributeName(i);
			String attributeValue=parser.getAttributeValue(i);
			
			if(attributeName.equals("id"))
			{
				id=Integer.parseInt(attributeValue);
			}
		}
		
		try 
		{
			int eventType = parser.next();
			String tagName=null;
			
			while (eventType != XmlPullParser.END_DOCUMENT) 
			{
				if (eventType == XmlPullParser.START_TAG) 
				{
					tagName=parser.getName();
					
					if(tagName!=null && tagName.equals("phone"))
					{
						String number=null;
						int type=0;
						String label=null;
	
						attributeCount=parser.getAttributeCount();
						for(int i= 0; i < attributeCount;i++)
						{
							String attributeName=parser.getAttributeName(i);
							String attributeValue=parser.getAttributeValue(i);
							
							if(attributeName.equals("number"))
							{
								number=attributeValue;
							}
							else if(attributeName.equals("label"))
							{
								label=attributeValue;
							}
							else if(attributeName.equals("type"))
							{
								type=Integer.parseInt(attributeValue);
							}
						}
						
						PhoneStruct phone=new PhoneStruct();
						phone.setNumber(number);
						phone.setType(type);
						phone.setLabel(label);
						
						phoneStructArray.add(phone);
					}
					else if(tagName!=null && tagName.equals("email"))
					{
						String value=null;
						int type=0;
						String label=null;
	
						attributeCount=parser.getAttributeCount();
						for(int i= 0; i < attributeCount;i++)
						{
							String attributeName=parser.getAttributeName(i);
							String attributeValue=parser.getAttributeValue(i);
							
							if(attributeName.equals("value"))
							{
								value=attributeValue;
							}
							else if(attributeName.equals("label"))
							{
								label=attributeValue;
							}
							else if(attributeName.equals("type"))
							{
								type=Integer.parseInt(attributeValue);
							}
						}
						
						AttributeValueStruct emailStruct=new AttributeValueStruct(1);
						emailStruct.setValue(value,0);
						emailStruct.setType(type);
						emailStruct.setLabel(label);
						
						emailStructArray.add(emailStruct);
					}
					else if(tagName!=null && tagName.equals("address"))
					{
						String city=null;
						String street=null;
						String postcode=null;
						String region=null;
						String country=null;
						String pobox=null;
						String neighborhood=null;
						int type=0;
						String label=null;
	
						attributeCount=parser.getAttributeCount();
						for(int i= 0; i < attributeCount;i++)
						{
							String attributeName=parser.getAttributeName(i);
							String attributeValue=parser.getAttributeValue(i);
					
							if(attributeName.equals("city"))
							{
								city=attributeValue;
							}
							else if(attributeName.equals("street"))
							{
								street=attributeValue;
							}
							else if(attributeName.equals("postcode"))
							{
								postcode=attributeValue;
							}
							else if(attributeName.equals("region"))
							{
								region=attributeValue;
							}
							else if(attributeName.equals("country"))
							{
								country=attributeValue;
							}
							else if(attributeName.equals("pobox"))
							{
								pobox=attributeValue;
							}
							else if(attributeName.equals("neighborhood"))
							{
								neighborhood=attributeValue;
							}
							else if(attributeName.equals("label"))
							{
								label=attributeValue;
							}
							else if(attributeName.equals("type"))
							{
								type=Integer.parseInt(attributeValue);
							}	            		
						}
						
						AttributeValueStruct struct=new AttributeValueStruct(7);
						struct.setValue(city,0);
						struct.setValue(street,1);
						struct.setValue(postcode,2);
						struct.setValue(region,3);
						struct.setValue(country,4);
						struct.setValue(pobox,5);
						struct.setValue(neighborhood,6);
						struct.setType(type);
						struct.setLabel(label);
						
						addressStructArray.add(struct);
					}
					else if(tagName!=null && tagName.equals("organization"))
					{
						String company=null;
						String position=null;
						int type=0;
						String label=null;
	
						attributeCount=parser.getAttributeCount();
						for(int i= 0; i < attributeCount;i++)
						{
							String attributeName=parser.getAttributeName(i);
							String attributeValue=parser.getAttributeValue(i);
							
							if(attributeName.equals("company"))
							{
								company=attributeValue;
							}
							else if(attributeName.equals("position"))
							{
								position=attributeValue;
							}
							else if(attributeName.equals("label"))
							{
								label=attributeValue;
							}
							else if(attributeName.equals("type"))
							{
								type=Integer.parseInt(attributeValue);
							}
						}
						
						AttributeValueStruct struct=new AttributeValueStruct(2);
						struct.setValue(company,0);
						struct.setValue(position,1);
						struct.setType(type);
						struct.setLabel(label);
						
						organizationStructArray.add(struct);
					}
					else if(tagName!=null && tagName.equals("icon"))
					{
						attributeCount=parser.getAttributeCount();
						for(int i= 0; i < attributeCount;i++)
						{
							String attributeName=parser.getAttributeName(i);
							String attributeValue=parser.getAttributeValue(i);
							
							if(attributeName.equals("start"))
							{
								iconStart=Integer.parseInt(attributeValue);
							}
							else if(attributeName.equals("length"))
							{
								iconLength=Integer.parseInt(attributeValue);
							}
						}
					}
				} 
				else if (eventType == XmlPullParser.TEXT) 
				{
					if(tagName!=null && tagName.equals("display_name"))
					{
						displayName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("name"))
					{
						//����symbian�汾
						String name=parser.getText();
						if(name.length()>0)
						{
							displayName=name;
						}
					}
					else if(tagName!=null && tagName.equals("family_name"))
					{
						familyName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("given_name"))
					{
						givenName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("middle_name"))
					{
						middleName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("prefix"))
					{
						prefix=parser.getText();
					}
					else if(tagName!=null && tagName.equals("suffix"))
					{
						suffix=parser.getText();
					}
					else if(tagName!=null && tagName.equals("phonetic_family_name"))
					{
						phoneticFamilyName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("phonetic_given_name"))
					{
						phoneticGivenName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("phonetic_middle_name"))
					{
						phoneticMiddleName=parser.getText();
					}
					else if(tagName!=null && tagName.equals("ringTone"))
					{
						ringTone=parser.getText();
					}
					//for symbian version
					else if(tagName!=null && tagName.equals("phone"))
					{
						String number=parser.getText();
						
						if(phoneStructArray.size()>0)
						{
							PhoneStruct phone=phoneStructArray.get(phoneStructArray.size()-1);
							phone.setNumber(number);
							phone.setType(1);
							phone.setLabel(context.getString(R.string.other));
						}
						else
						{
							PhoneStruct phone=new PhoneStruct();
							phone.setNumber(number);
							phone.setType(1);
							phone.setLabel(context.getString(R.string.other));
							
							phoneStructArray.add(phone);
						}
					}
				}
				else if (eventType == XmlPullParser.END_TAG) 
				{
					tagName=parser.getName();
					if(tagName.equals("contact"))
					{
						break;
					}
				}
				
				eventType = parser.next();
			}
		} 
		catch (XmlPullParserException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
	
	static public Cursor openContactCursor(Context context,String contactIdselection,boolean in) 
	{
		if(contactIdselection!=null)
		{
			String inStr="";
			if(in)
			{
				inStr=" in ";
			}
			else
			{
				inStr=" not in ";
			}
			
			contactIdselection=ContactsContract.Contacts._ID+inStr+contactIdselection;
		}

		String sortOrder="sort_key_alt";
		Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, contactIdselection, null, sortOrder);
		return cursor;
	}
	
	static public int contactCount(Context context)
	{
		//String[] columns={"count(*) as totalCount"};//report error
		Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
		cursor.moveToFirst();
		int count=cursor.getCount();
		cursor.close();
		return count;
	}
}
